package com.well.kernel.util.httpclient;

import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.log4j.Logger;

import java.util.List;

/**
 * Copyright &copy; Well All rights reserved.
 * Author:Well
 * Date:2017-07-01
 * Description:httpclient异步请求的利用类
 */

public class HttpAsyncClientUtil
{
    private static Logger logger=Logger.getLogger(HttpAsyncClientUtil.class);

    private static CloseableHttpAsyncClient client=null;

    static
    {
        try
        {
            /* 自定义的socket工厂类可以和指定的协议(http、https)联系起来，用来创建自定义的连接管理器 */
            NoopIOSessionStrategy niIOSS= NoopIOSessionStrategy.INSTANCE;
            SSLIOSessionStrategy sslIOSSS=SSLIOSessionStrategy.getDefaultStrategy();
            Registry<SchemeIOSessionStrategy> registry = RegistryBuilder
                    .<SchemeIOSessionStrategy> create()
                    .register("http", niIOSS)
                    .register("https", sslIOSSS).build();
            /* 初始化连接池管理器 */
            ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
            PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor,registry);
            connectionManager.setMaxTotal(HttpClientUtil.MAX_TOTAL_CONNECTIONS);
            connectionManager.setDefaultMaxPerRoute(HttpClientUtil.MAX_ROUTE_CONNECTIONS);
            /* 请求配置 */
            RequestConfig config= RequestConfig.custom()
                    .setConnectionRequestTimeout(HttpClientUtil.CONNECTION_REQUEST_TIMEOUT)
                    .setConnectTimeout(HttpClientUtil.CONNECT_TIMEOUT)
                    .setSocketTimeout(HttpClientUtil.SOCKET_TIMEOUT)
                    .setRedirectsEnabled(true).build();

            /* cookie */
            CookieStore cookieStore=new BasicCookieStore();
            /* client构建器 */
            HttpAsyncClientBuilder clientBuilder= HttpAsyncClients.custom()
                    .setConnectionManager(connectionManager)
                    .setDefaultCookieStore(cookieStore);
            /* 初始化client */
            client=clientBuilder.setDefaultRequestConfig(config).build();
            client.start();
        }
        catch (Exception e)
        {
            logger.error(e);
        }
    }

    /**
     * 异步get请求
     * @param uri
     * @param httpResponseFutureCallback
     */
    public static void get(String uri,HttpResponseFutureCallback httpResponseFutureCallback)
    {
        final HttpGet get=new HttpGet(uri);
        client.execute(get,httpResponseFutureCallback);
    }

    /**
     * 异步post请求，无参数
     * @param uri
     * @param httpResponseFutureCallback
     */
    public static void post(String uri,HttpResponseFutureCallback httpResponseFutureCallback)
    {
        post(uri,null,httpResponseFutureCallback);
    }

    /**
     * 异步post请求，有参数
     * @param uri
     * @param params
     * @param httpResponseFutureCallback
     */
    public static void post(String uri,List<NameValuePair> params,HttpResponseFutureCallback httpResponseFutureCallback)
    {
        try
        {
            final HttpPost post = new HttpPost(uri);
            if (null != params)
            {
                post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            }
            client.execute(post,httpResponseFutureCallback);
        }
        catch (Exception e)
        {
            logger.error(e);
        }
    }

}
